package cn.ulyer.core.secure.service;

import cn.ulyer.common.jpa.entity.Permission;
import cn.ulyer.common.jpa.entity.QUser;
import cn.ulyer.common.jpa.entity.Role;
import cn.ulyer.common.security.LoginUser;
import cn.ulyer.core.modules.system.service.PermissionService;
import cn.ulyer.core.modules.system.service.RoleService;
import cn.ulyer.core.modules.system.vo.PermissionVo;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class DbUserDetailService implements UserDetailsService {

    @Autowired
    private JPAQueryFactory queryFactory;

    @Autowired
    private RoleService roleService;

    @Autowired
    private PermissionService permissionService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        QUser user = QUser.user;
        LoginUser loginUser = queryFactory.select(Projections.bean(LoginUser.class,
                user.id,user.username,user.nickname,user.accountLocked, user.avatar,
                user.createTime,user.deptId,user.email,user.enable,user.expireTime,
                user.updateTime,user.remark,user.password,user.phone)).from(user).where(user.username.eq(username)).fetchOne();
        if(loginUser == null){
            throw new UsernameNotFoundException("用户未找到");
        }
        if(!loginUser.isAccountNonExpired()){
            throw new AccountExpiredException("帐号已过期");
        }
        Set<String> authoritySet = new HashSet<>();
        List<Role> roles = roleService.userRolesById(loginUser.getId());
        if(roles != null){
            roles.forEach(r->authoritySet.add(r.getRoleValue()));
            List<PermissionVo> permissionVoList = permissionService.PermissionVoByRoles(roles, Permission.PermissionType.API);
            if(permissionVoList != null ){
                permissionVoList.forEach(p->authoritySet.add(p.getPermValue()));
            }
        }
        loginUser.setPermissions(authoritySet);
        return loginUser;
    }



}
